package com.chezhujie.www.service;

import com.xy.core.init.mysql.ColumnClass;
import com.xy.core.init.mysql.EntityClass;
import com.xy.core.init.mysql.annotation.SelectMap;
import com.xy.core.utils.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.xy.core.init.mysql.annotation.Enum;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by 汤伟杰 on 2017/5/22.
 */
@Service
public class GenerateService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    private static Map<String, String> switchMap = new HashMap<String, String>();
    private static Map<String, String> selectMap = new HashMap<String, String>();
    private static String packagePath = "com.chezhujie.www";
    private static String classpath =String.valueOf(Thread.currentThread().getContextClassLoader().getResource("")).substring(6);
    private static String entityPath ="domain";
    private static String enumsPath ="enums";

    private void init(){
        switchMap = new HashMap<String, String>();
        selectMap = new HashMap<String, String>();
    }

    public String createTableSql(String tablename) throws Exception{
        Class<?> clazz = Class.forName(tablename);
        Object obj=clazz.newInstance();
        Method method = clazz.getMethod("create", new Class[]{});
        Object object = method.invoke(obj, null);
        String sql = String.valueOf(object);
        return sql;
    }

    public void update(String sql) throws Exception {

        jdbcTemplate.execute(sql);
    }
    public void generateCode() throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("nihao", "xxxxxxxxxxxxxxxxxxxxxx");
        Freemarker.print("test.ftl",map,"mapper/");
    }

    public void downloadTemplate(String classname, HttpServletResponse resp) throws Exception {
        init();

        System.out.println("清空："+ PathUtil.getClasspath()+"admin/ftl");
        DelAllFile.delFolder(PathUtil.getClasspath()+"admin/ftl"); //生成代码前,先清空之前生成的代码
        String filePath = "admin/ftl/code/";

        
        Map<String,Object> root = new HashMap<String,Object>();		//创建数据模型
        setMapData(root,classname);

        /*生成controller*/
        String controller = "com/chezhujie/www/controller";
        Freemarker.printFile("TemplateController.ftl", root,"code/java/"+controller+"/"+root.get("simpleClassName")+"Controller.java", filePath, controller);
		/*生成service*/
        String service = "com/chezhujie/www/service";
        Freemarker.printFile("TemplateService.ftl", root, "code/java/"+service+"/"+root.get("simpleClassName")+"Service.java", filePath, service);
		/*生成mapper*/
        String mapper = "com/chezhujie/www/persistence";
        Freemarker.printFile("TemplateMapper.ftl", root, "code/java/"+mapper+"/"+root.get("simpleClassName")+"Mapper.java", filePath, mapper);
        /*生成*mapper.xml*/
        String mapperxml = "mapper";
        Freemarker.printFile("TemplateMapper.ftl", root, "code/resources/"+mapperxml+"/"+root.get("simpleClassName")+"Mapper.xml", filePath, mapperxml);
        /*生成 视图列表/list.html*/
        String viewList = "view";
        Freemarker.printFile("list.ftl", root, "code/webapp/WEB-INF/"+viewList+"/"+root.get("simpleClassname")+"/list.html", filePath, viewList);
//        /*生成 视图详情并编辑/detail.html*/
        String viewDetail = "view";
        Freemarker.printFile("detail.ftl", root, "code/webapp/WEB-INF/"+viewList+"/"+root.get("simpleClassname")+"/detail.html", filePath, viewDetail);
        /*生成 视图列表/list.html*/
        String viewAdd = "view";
        Freemarker.printFile("add.ftl", root, "code/webapp/WEB-INF/"+viewList+"/"+root.get("simpleClassname")+"/add.html", filePath, viewAdd);
        /*生成 api测试页面/apiTest.ftl*/
//        String apiTest = "view";
//        Freemarker.printFile("apiTest.ftl", root, "code/webapp/WEB-INF/"+viewList+"/"+root.get("simpleClassname")+"/apiTest.html", filePath, apiTest);





        	/*生成的全部代码压缩成zip文件*/
        if(FileZip.zip(PathUtil.getClasspath()+"admin/ftl/code", PathUtil.getClasspath()+"admin/ftl/code.zip")){

			/*下载代码*/
            FileDownload.fileDownload(resp, PathUtil.getClasspath()+"admin/ftl/code.zip", "code.zip");
        }

    }
/*
    public static void main(String[] args) throws Exception {
        System.out.println("清空："+PathUtil.getClasspath()+"admin/ftl");
        DelAllFile.delFolder(PathUtil.getClasspath()+"admin/ftl"); //生成代码前,先清空之前生成的代码
        String filePath = "admin/ftl/code/";

        String classname = "com.chezhujie.www.domain.Shop";
        Map<String,Object> root = new HashMap<String,Object>();		//创建数据模型
        setMapData(root,classname);
        String mapperxml = "mapper/";
        Freemarker.print("TemplateMapper.ftl", root, mapperxml);

    }*/

    private static void setMapData(Map<String, Object> root, String classname) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        getEnumSwitchMap();
        String simpleClassName = classname.substring(classname.lastIndexOf(".")+1);
        String simpleClassname = simpleClassName.toLowerCase();
        root.put("simpleClassName", simpleClassName);
        root.put("simpleClassname", simpleClassname);

        EntityClass entityclass = new EntityClass(classname);

        root.put("primaryId", entityclass.getTable().getPrimaryKey());
        root.put("keyProperties", entityclass.getTable().getKeyProperties());
        root.put("keyTypeSimple", entityclass.getTable().getKeyTypeSimple());
        root.put("keyPropertiesUp", entityclass.getTable().getKeyPropertiesUp());
        root.put("tablename", entityclass.getTable().getName());


        root.put("columnList", entityclass.getColumn());

        root.put("describe", entityclass.getTable().getDescribe());
        root.put("date", sdf.format(new Date()));


        root.put("hasFile", 0);
        root.put("hasDate", 0);
        root.put("hasSwitch", 0);
        root.put("hasSelect", 0);
        root.put("hasText", 0);
        root.put("hasInt", 0);
        root.put("hasHidden", 0);
        root.put("hasString", 0);

        List<Map<String, Object>> listSwitch = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> listFile = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> listSelect = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> listText = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> listInt = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> listHidden = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> listString = new ArrayList<Map<String, Object>>();

        for (ColumnClass columnClass : entityclass.getColumn()) {
            if("String".equals(columnClass.getClasstypeSimple())){
                root.put("hasString", 1);
                Map<String, Object> mapobj = new HashMap<String, Object>();
                mapobj.put("properties", columnClass.getProperties());
                mapobj.put("describe", columnClass.getDescribe());
                mapobj.put("propertiesUp", columnClass.getPropertiesUp());
                mapobj.put("length", columnClass.getLength());
                listString.add(mapobj);
            }

            if ("file".equals(columnClass.getInputType())) {
                root.put("hasFile", 1);
                Map<String, Object> mapobj = new HashMap<String, Object>();
                mapobj.put("properties", columnClass.getProperties());
                mapobj.put("describe", columnClass.getDescribe());
                mapobj.put("propertiesUp", columnClass.getPropertiesUp());
                mapobj.put("length", columnClass.getLength());
                listText.add(mapobj);

            } else if ("date".equals(columnClass.getInputType())) {
                root.put("hasDate", 1);
            } else if ("switch".equals(columnClass.getInputType())) {
                //switch 只有两个属性，是和否 或者其他
                root.put("hasSwitch", 1);
                Map<String, Object> mapobj = new HashMap<String, Object>();
                mapobj.put("name", columnClass.getProperties());
                mapobj.put("nameUp", columnClass.getPropertiesUp());

                String switchclassname = switchMap.get(columnClass.getInputCode());
                if(switchclassname==null){
                    throw new ClassNotFoundException(columnClass.getInputType()+"不存在该 inputCode="+columnClass.getInputCode()+"!");
                }else{
                    mapobj.put("switch", SelectMap.getListMapByEnum(switchclassname));//1和0
                }
                mapobj.put("switchCode", columnClass.getInputCode());
                listSwitch.add(mapobj);
            } else if ("select".equals(columnClass.getInputType())) {
                //select 有多个属性
                root.put("hasSelect", 1);
                Map<String, Object> mapobj = new HashMap<String, Object>();
                mapobj.put("name", columnClass.getProperties());
                mapobj.put("nameUp", columnClass.getPropertiesUp());
                String selectclassname = selectMap.get(columnClass.getInputCode());
                if(selectclassname!=null) {
                    mapobj.put("select",SelectMap.getListMapByEnum(selectclassname));//动态select
                }else if("int".equals(columnClass.getInputCode())){
                    mapobj.put("select", new ArrayList<Map<String,Object>>());

                }else if("str".equals(columnClass.getInputCode())){
                    mapobj.put("select", new ArrayList<Map<String,Object>>());
                }else{
                    throw new ClassNotFoundException(columnClass.getInputType() + "不存在该 inputCode=" + columnClass.getInputCode() + "!");
                }
                mapobj.put("selectCode", columnClass.getInputCode());
                listSelect.add(mapobj);
            } else if ("text".equals(columnClass.getInputType())) {
                root.put("hasText", 1);
                Map<String, Object> mapobj = new HashMap<String, Object>();
                mapobj.put("properties", columnClass.getProperties());
                mapobj.put("describe", columnClass.getDescribe());
                mapobj.put("propertiesUp", columnClass.getPropertiesUp());
                mapobj.put("length", columnClass.getLength());
                listText.add(mapobj);
            } else if ("int".equals(columnClass.getInputType())) {
                root.put("hasInt", 1);
                Map<String, Object> mapobj = new HashMap<String, Object>();
                mapobj.put("properties", columnClass.getProperties());
                mapobj.put("describe", columnClass.getDescribe());
                mapobj.put("propertiesUp", columnClass.getPropertiesUp());
                mapobj.put("length", columnClass.getLength());
                listInt.add(mapobj);

            } else if ("hidden".equals(columnClass.getInputType())) {
                root.put("hasInt", 1);
                Map<String, Object> mapobj = new HashMap<String, Object>();
                mapobj.put("properties", columnClass.getProperties());
                mapobj.put("describe", columnClass.getDescribe());
                mapobj.put("propertiesUp", columnClass.getPropertiesUp());
                listHidden.add(mapobj);
            }
        }
        root.put("listSwitch", listSwitch);
        root.put("listFile", listFile);
        root.put("listSelect", listSelect);
        root.put("listText", listText);
        root.put("listInt", listInt);
        root.put("listHidden", listHidden);
        root.put("listString", listString);



    }

    public List<String> getEntity() {
        String p = getLocationPath(entityPath);
        File file = new File(p);
        File[] listfile = file.listFiles();
        List<String> list = new ArrayList<String>();
        for (File file1 : listfile) {
            if(file1.isFile()){
                list.add(packagePath+"."+entityPath+"."+file1.getName().substring(0,file1.getName().lastIndexOf(".")));
            }
        }

        return list;
    }

    /**
     *
     * @param path entityPath 、 enumsPath
     * @return
     */
    private static String getLocationPath(String path) {
        String p = classpath;
        p += (packagePath+"."+path).replaceAll("\\.", "/");
        return p;
    }

    public static void getEnumSwitchMap() throws ClassNotFoundException {
        String path = getLocationPath(enumsPath);
        File file = new File(path);
        File[] files = file.listFiles();
        for (File file1 : files) {
            if(file1.isFile()){
                String name  = file1.getName();
                if(name.endsWith(".class")){
                    name = name.substring(name.lastIndexOf("/")+1,name.lastIndexOf("."));
                    Class<?> clazz = Class.forName(packagePath + "." + enumsPath + "." + name);
                    Enum annon = clazz.getAnnotation(Enum.class);
                    String nameEnum = null;
                    if(annon!=null){
                        if(StringUtils.isNotBlank(annon.name())){
                            nameEnum = annon.name();
                        }else{
                            nameEnum = clazz.getSimpleName();
                        }
                        if("switch".equals(annon.type())){//switch
                            switchMap.put(nameEnum,packagePath+"."+enumsPath+"."+clazz.getSimpleName());
                        }else if("select".equals(annon.type())){//select
                            selectMap.put(nameEnum,packagePath+"."+enumsPath+"."+clazz.getSimpleName());
                        }
                    }
                }
            }
        }
    }

/*    public static void main(String[] args) throws Exception {
        getEnumSwitchMap();
        SelectMap.getListMapByEnum(selectMap.get("yesorno"));
    }*/
}
